﻿using System;
using System.Text;
using smp.QueryDb.Structure;

namespace smp.QueryDb
{
    public class Query
    {
        #region temp while i build
        public void PrintSqlStatement()
        {
            Console.WriteLine();
            var adapter = new SqlAdapter();
            Structure.Finalise(adapter, true);
            var command = Structure.GenerateSelectAllCommand();
            Console.WriteLine("SELECT " + Structure.ColumnStatement);
            Console.WriteLine("FROM " + Structure.FromStatement);
            Console.WriteLine("WHERE " + Structure.WhereStatement);
            Console.WriteLine("ORDER BY " + Structure.OrderStatement);

            var text = new StringBuilder();
            text.AppendLine(command.CommandText);
            text.AppendLine("PARAMETERS : ");
            if (command.Parameters != null)
            {
                foreach (var parameter in command.Parameters)
                {
                    text.AppendLine(string.Format("{0}  |  {1}  |  {2}", parameter.Name, parameter.DataType, parameter.Value));
                }
            }
            Console.WriteLine(text.ToString());
            Console.WriteLine();
        }
        public void PrintPagedSqlStatement()
        {
            Console.WriteLine();
            var adapter = new SqlAdapter();
            Structure.Finalise(adapter, true);
            var command = Structure.GenerateSelectAllCommand();
            Console.WriteLine("SELECT " + Structure.ColumnStatement);
            Console.WriteLine("FROM " + Structure.FromStatement);
            Console.WriteLine("WHERE " + Structure.WhereStatement);
            Console.WriteLine("ORDER BY " + Structure.OrderStatement);

            var text = new StringBuilder();
            text.AppendLine(command.CommandText);
            text.AppendLine("PARAMETERS : ");
            if (command.Parameters != null)
            {
                foreach (var parameter in command.Parameters)
                {
                    text.AppendLine(string.Format("{0}  |  {1}  |  {2}", parameter.Name, parameter.DataType, parameter.Value));
                }
            }
            Console.WriteLine(text.ToString());
            Console.WriteLine();
        }
        #endregion

        private readonly QueryStructure _structure;

        public Query()
        {
            _structure = new QueryStructure();
        }

        internal QueryStructure Structure { get { return _structure; } }

        public Query Select(Column column)
        {
            _structure.Select(column);
            return this;
        }

        public Query From(Table table)
        {
            if (_structure.Table != null)
            {
                throw Helper.Error("Duplicate from declaration on query, can only declare From value once.");
            }
            _structure.SetFromStatement(table);
            return this;
        }

        public Query Where(Filter filter)
        {
            _structure.SetFilter(filter.Structure);
            return this;
        }

        public Query OrderBy(Column column)
        {
            _structure.AddSort(new Sort(column, false));
            return this;
        }

        public Query OrderByDescending(Column column)
        {
            _structure.AddSort(new Sort(column, true));
            return this;
        }

        public Query GroupBy(Column column)
        {
            _structure.AddGroupBy(new Group(column));
            return this;
        }
        
        public IQueryPage TakePage(int pageNumber)
        {
            _structure.SetPage(pageNumber);
            return new QueryPage(this);
        }

        public Query Top(int number)
        {
            _structure.SetTop(number);
            return this;
        }
    }
}
